package tokenizer;

import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharacterCodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;


	public class NewLineTokenizer implements Tokenizer {

		private final String _messageSeparator;

		private final StringBuffer _stringBuf = new StringBuffer();

		private final CharsetDecoder _decoder;
		private final CharsetEncoder _encoder;

		public NewLineTokenizer(String separator, Charset charset) {
			this._messageSeparator = separator;

			this._decoder = charset.newDecoder();
			this._encoder = charset.newEncoder();
		}

		/**
		 * Add some bytes to the message.  
		 * Bytes are converted to chars, and appended to the internal StringBuffer.
		 * Complete messages can be retrieved using the nextMessage() method.
		 *
		 * @param bytes an array of bytes to be appended to the message.
		 */
		public synchronized void addBytes(ByteBuffer bytes) {
			CharBuffer chars = CharBuffer.allocate(bytes.remaining());
			this._decoder.decode(bytes, chars, false); // false: more bytes may follow. Any unused bytes are kept in the decoder.
			chars.flip();
			this._stringBuf.append(chars);
		}

		/**
		 * Is there a complete message ready?.
		 *
		 * @return true the next call to nextMessage() will not return null, false otherwise.
		 */
		public synchronized boolean hasMessage() {
			return this._stringBuf.indexOf(this._messageSeparator) > -1;
			//return this._stringBuf.length()>0;
		}

		/**
		 * Get the next complete message if it exists, advancing the tokenizer to the next message.
		 * @return the next complete message, and null if no complete message exist.
		 */
		public synchronized String nextMessage() {
			String message = null;
			int messageEnd = this._stringBuf.indexOf(this._messageSeparator);
			if (messageEnd > -1) {
				message = this._stringBuf.substring(0, messageEnd);
				this._stringBuf.delete(0, messageEnd+this._messageSeparator.length());
			}
			return message;
		}

		/**
		 * Convert the String message into bytes representation, taking care of encoding and framing.
		 *
		 * IGNORE THIS ONE IN TIRGUL 11
		 *
		 * @return a ByteBuffer with the message content converted to bytes, after framing information has been added.
		 */
		public ByteBuffer getBytesForMessage(String msg)  throws CharacterCodingException {
			StringBuilder sb = new StringBuilder(msg);
			sb.append(this._messageSeparator);
			ByteBuffer bb = this._encoder.encode(CharBuffer.wrap(sb));
			return bb;
		}
		public String toString()
		{
			
			return "buffer " + this._stringBuf.substring(0, 10) + " end buffer";
		}
	}



